#include <time.h>
#include <stdio.h>
#include "core/rpc_acs_request.h"
#include "core/auth/credential.h"
#include "core/auth/i_signer.h"

namespace aliyun {

RpcAcsRequest::RpcAcsRequest(const string& product, const string& version, const string& action)
  : AcsRequest(product, version, action) {
  SetMethod("GET");
  SetAcceptFormat("JSON");
}

RpcAcsRequest::~RpcAcsRequest() {
}

string RpcAcsRequest::ComposeUrl(ISigner *i_signer, const Credential* credential, const string& domain) {
  if(NULL == i_signer || NULL == credential) {
    return "";
  }
  query_parameters_["RegionId"] = GetRegionId();
  query_parameters_["AccessKeyId"] = credential->GetAccessKeyId();
  query_parameters_["Format"] = GetAcceptFormat();
  query_parameters_["SignatureMethod"] = i_signer->GetSignatureMethod();
  query_parameters_["SignatureVersion"] = i_signer->GetSignatureVersion();
  query_parameters_["SignatureNonce"] = string_Uuid(credential->GetAccessKeyId());
  time_t current_time = time(NULL);
  struct tm *gmt = gmtime(&current_time);
  char time_buffer[64];
  sprintf(time_buffer, "%04d-%02d-%02dT%02d:%02d:%02dZ", gmt->tm_year + 1900,
    gmt->tm_mon+1, gmt->tm_mday, gmt->tm_hour, gmt->tm_min, gmt->tm_sec);
  query_parameters_["Timestamp"] = time_buffer;
  query_parameters_["Action"] = GetAction();
  query_parameters_["Version"] = GetVersion();
  query_parameters_["Signature"] = ComputeSignature(query_parameters_, credential->GetAccessSecret(), i_signer);
  string request_url = GetProtocol() + "://"+ domain + "/?";

  std::map<string, string>::iterator iter;
  for(iter = query_parameters_.begin(); iter != query_parameters_.end(); iter++) {
    request_url += iter->first + "=" + string_UrlEncode(iter->second) + "&";
  }
  return request_url.substr(0, request_url.length()-1);
}

string RpcAcsRequest::ComputeSignature(std::map<string, string>& parameters, const string& access_secret, ISigner *i_signer) {
  string canonicalized_query_string;
  std::map<string, string>::iterator iter;
  for(iter = parameters.begin(); iter != parameters.end(); iter++) {
    canonicalized_query_string += "&" + string_UrlPrecentEncode(iter->first) + "=" + string_UrlPrecentEncode(iter->second);
  }
  string string_to_sign = GetMethod() + "&%2F&" + string_UrlPrecentEncode(
    canonicalized_query_string.substr(1, canonicalized_query_string.length()));
  return i_signer->SignString(string_to_sign, access_secret+"&");
}

} // namespace aliyun {

// end of file
